package com.qutan.app.quartz.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * Created by pengweiyuan on 6/17/16.
 */
public class HttpUtils {

    // 创建httpclient连接池
    private PoolingHttpClientConnectionManager httpClientConnectionManager = null;

    private static final HttpUtils httpUtils=new HttpUtils();

    public static final HttpUtils getInstance(){
        return httpUtils;
    }

    /**
     * 私有的构造函数
     */
    private HttpUtils(){
        //初始化httpClient
        initHttpClient();
    }

    public void initHttpClient() {
        //创建httpclient连接池
        httpClientConnectionManager = new PoolingHttpClientConnectionManager();
        //设置连接池最大数量
        httpClientConnectionManager.setMaxTotal(100);
        //设置单个路由最大连接数量
        httpClientConnectionManager.setDefaultMaxPerRoute(50);
    }

    //请求重试机制
    private HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
        public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            if (executionCount >= 3) {
                // 超过三次则不再重试请求
                return false;
            }
            if (exception instanceof InterruptedIOException) {
                // Timeout
                return false;
            }
            if (exception instanceof UnknownHostException) {
                // Unknown host
                return false;
            }
            if (exception instanceof ConnectTimeoutException) {
                // Connection refused
                return false;
            }
            if (exception instanceof SSLException) {
                // SSL handshake exception
                return false;
            }
            HttpClientContext clientContext = HttpClientContext.adapt(context);
            HttpRequest request = clientContext.getRequest();
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            if (idempotent) {
                // Retry if the request is considered idempotent
                return true;
            }
            return false;
        }
    };


    public CloseableHttpClient getHttpClient() {
        // 创建全局的requestConfig
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(3000)
                .setCookieSpec(CookieSpecs.BEST_MATCH).build();
        // 声明重定向策略对象
        LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
                .setDefaultRequestConfig(requestConfig)
                .setRedirectStrategy(redirectStrategy)
                .setRetryHandler(myRetryHandler)
                .build();
        return httpClient;
    }


    public String httpGet(String urlString) {
        String src = "";
        if (StringUtils.isBlank(urlString) || !urlString.startsWith("http")) {//如果urlString为null或者urlString为空，或urlString非http开头，返回src空值
            return src;
        }
        //创建response
        CloseableHttpResponse response = null;
        HttpGet httpGet = null;
        urlString = urlString.trim();//防止传入的urlString首尾有空格
        //转化String url为URI,解决url中包含特殊字符的情况
        try {
            URL url = new URL(urlString);
            // URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
            httpGet = new HttpGet(urlString);
            //设置请求头
            httpGet.addHeader("Accept", "*/*");
            //httpGet.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            httpGet.addHeader("Connection", "keep-alive");
            //httpGet.addHeader("Content-Type", "application/json");//参数格式:json
            response = getHttpClient().execute(httpGet);
            //得到响应状态码
            int statuCode = response.getStatusLine().getStatusCode();

            if (statuCode == HttpStatus.SC_OK) {
                //获得响应实体
                HttpEntity entity = response.getEntity();
                src = EntityUtils.toString(response.getEntity());
            } else {

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            httpGet.abort();
        }
        return src;
    }


    public String httpPost(String urlString, Map<String, String> params) {
        String src = "";
        if (StringUtils.isBlank(urlString) || !urlString.startsWith("http")) {//如果urlString为null或者urlString为空，或urlString非http开头，返回src空值
            return src;
        }
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();//参数
        //设置Http Post数据
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                nvps.add(pair);
            }
        }
        //创建response
        CloseableHttpResponse response = null;
        HttpPost httpPost = null;
        urlString = urlString.trim();//防止传入的urlString首尾有空格
        //转化String url为URI,解决url中包含特殊字符的情况
        try {
            URL url = new URL(urlString);
            httpPost = new HttpPost(urlString);
            httpPost.addHeader("Content-Type", "application/json");
            StringEntity entity = new StringEntity(JSON.toJSONString(params), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            //httpPost.setEntity(new UrlEncodedFormEntity(nvps));//设置请求参数
            response = getHttpClient().execute(httpPost);
            //得到响应状态码
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == HttpStatus.SC_OK) {
                //获得响应实体
                src = EntityUtils.toString(response.getEntity());
            } else {
                System.err.println(statusCode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            httpPost.abort();
        }
        return src;
    }

    public static void main(String[] args) {
        //initHttpClient();
        // String url="http://localhost:8801/api/test2";
        //httpGet(url);

        Map<String, String> postMap = new HashMap<>();
        postMap.put("ddcccc", "cccc");
        String url = "http://localhost:8801/api/test";
        System.err.println(HttpUtils.getInstance().httpPost(url, postMap));

    }

}
